package cn.akira.domain.strategy.service.raffle;

import cn.akira.domain.strategy.model.entity.StrategyAwardEntity;
import cn.akira.domain.strategy.model.entity.StrategyEntity;
import cn.akira.domain.strategy.model.vo.RuleTreeVO;
import cn.akira.domain.strategy.model.vo.RuleWeightVO;
import cn.akira.domain.strategy.model.vo.StrategyAwardRuleModelVO;
import cn.akira.domain.strategy.model.vo.StrategyAwardStockKeyVO;
import cn.akira.domain.strategy.repository.IStrategyRepository;
import cn.akira.domain.strategy.service.rule.chain.factory.DefaultChainFactory;
import cn.akira.domain.strategy.service.rule.chain.factory.engine.ILogicChainEngine;
import cn.akira.domain.strategy.service.rule.tree.factory.DefaultTreeFactory;
import cn.akira.domain.strategy.service.rule.tree.factory.engine.IDecisionTreeEngine;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author fjl95
 * @date 2025/5/13
 * @description 规则校验具体实现
 */
@Slf4j
@Service
public class DefaultRaffleStrategy extends AbstractRaffleStrategy implements IRaffleAward,IRaffleStock,IRaffleRule{


    @Resource
    private IStrategyRepository strategyRepository;

    @Resource
    private DefaultTreeFactory treeFactory;

    @Resource
    private DefaultChainFactory chainFactory;

    public DefaultRaffleStrategy(IStrategyRepository strategyRepository, DefaultChainFactory defaultChainFactory, DefaultTreeFactory defaultTreeFactory) {
        super(strategyRepository, defaultChainFactory, defaultTreeFactory);
    }


    @Override
    public DefaultChainFactory.StrategyAwardVO raffleLogicChain(String userId, Long strategyId) {
        //查询数据库的链逻辑
        StrategyEntity strategy = strategyRepository.queryStrategyEntityByStrategyId(strategyId);
        String[] ruleModels = strategy.ruleModels();
        //传入链逻辑获得引擎
        ILogicChainEngine chainEngine = chainFactory.openChainGroup(ruleModels);
        //运行引擎
        return chainEngine.process(userId,strategyId);
    }

    @Override
    public DefaultTreeFactory.StrategyAwardVO raffleLogicTree(String userId, Long strategyId, Integer awardId) {


        return raffleLogicTree(userId,strategyId,awardId,null);
    }

    @Override
    public DefaultTreeFactory.StrategyAwardVO raffleLogicTree(String userId, Long strategyId, Integer awardId, Date endDateTime) {
        //查询并装配数据库的树逻辑
        StrategyAwardRuleModelVO ruleModelVO = strategyRepository.queryStrategyAwardRuleModelVO(strategyId,awardId);
        if (ruleModelVO == null) {
            return DefaultTreeFactory.StrategyAwardVO.builder().awardId(awardId).build();
        }
        RuleTreeVO ruleTreeVO = strategyRepository.queryRuleTreeVOByTreeId(ruleModelVO.getRuleModels());
        if (null == ruleTreeVO) {
            throw new RuntimeException("存在抽奖策略配置的规则模型 Key，未在库表 rule_tree、rule_tree_node、rule_tree_line 配置对应的规则树信息 " + ruleModelVO.getRuleModels());
        }
        //传入树逻辑并获得引擎
        IDecisionTreeEngine treeEngine = treeFactory.openLogicTree(ruleTreeVO);
        //运行引擎
        return treeEngine.process(userId,strategyId,awardId,endDateTime);
    }


    //取出减库存堵塞队列的第一个任务
    @Override
    public StrategyAwardStockKeyVO takeQueueValue() throws InterruptedException {
        return strategyRepository.takeQueueValue();
    }

    //对数据库库存的减少操作
    @Override
    public void updateStrategyAwardStock(Long strategyId, Integer awardId) {
        strategyRepository.updateStrategyAwardStock(strategyId,awardId);
    }

    //
    @Override
    public List<StrategyAwardEntity> queryRaffleStrategyAwardList(Long strategyId) {
        return strategyRepository.queryStrategyAwardList(strategyId);
    }

    @Override
    public List<StrategyAwardEntity> queryRaffleStrategyAwardListByActivityId(Long activityId) {
        Long strategyId = strategyRepository.queryStrategyIdByActivityId(activityId);
        return queryRaffleStrategyAwardList(strategyId);
    }

    @Override
    public Map<String, Integer> queryAwardRuleLockCount(String[] treeIds) {
        return strategyRepository.queryAwardRuleLockCount(treeIds);
    }




}
